package com.iwhalecloud.uncc.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public final class JsonUtil {

	private JsonUtil() {
	}

	/**
	 * json取值
	 *
	 * @param jsonStr
	 * @param jsonPath
	 */

	public static String getValue(String jsonStr, String jsonPath) {
		if (jsonStr.trim().startsWith("[")) {
			JSONArray arr = JSONObject.parseArray(jsonStr);
			return getArrayValue(arr, jsonPath);
		} else {
			JSONObject obj = JSONObject.parseObject(jsonStr);
			return getValue(obj, jsonPath);
		}
	}

	/**
	 * json取值
	 *
	 * @param jsonStr
	 * @param jsonPath
	 */

	public static List<String> getValueArray(String jsonStr, String jsonPath)  {
		if (jsonStr.trim().startsWith("[")) {
			JSONArray arr = JSONObject.parseArray(jsonStr);
			return getArrayArray(arr, jsonPath);
		} else {
			JSONObject obj = JSONObject.parseObject(jsonStr);
			return getValueArray(obj, jsonPath);
		}
	}

	/**
	 * json取值
	 *
	 * @param jsonObject
	 * @param jsonPath
	 */

	public static List<String> getValueArray(JSONObject jsonObject, String jsonPath) {
		Object object = JSONPath.eval(jsonObject, jsonPath);
		List<String> result = new ArrayList<>();
		if (object != null && object instanceof JSONArray) {
			JSONArray arr = (JSONArray) object;
			for(Object o : arr){
				result.add(o.toString());
			}
		}
		return result;
	}


	/**
	 * json取值
	 *
	 * @param jsonObject
	 * @param jsonPath
	 */

	public static String getValue(JSONObject jsonObject, String jsonPath) {
		Object object = JSONPath.eval(jsonObject, jsonPath);
		String result = null;
		if (object != null && object instanceof JSONArray) {
			JSONArray arr = (JSONArray) object;
			if (!arr.isEmpty()) {
				result =arr.toJSONString();
			}
		} else if (object != null) {
			result = object.toString();
		}
		return result;
	}

	/**
	 * json取值
	 *
	 * @param jsonArray
	 * @param jsonPath
	 */

	public static String getArrayValue(JSONArray jsonArray, String jsonPath) {
		Object object = JSONPath.eval(jsonArray, jsonPath);
		String result = null;
		if (object != null && object instanceof JSONArray) {
			JSONArray arr = (JSONArray) object;
			if (!arr.isEmpty()) {
				result =arr.toJSONString();
			}
		} else if (object != null) {
			result = object.toString();
		}
		return result;
	}

	/**
	 * json取值
	 *
	 * @param jsonArray
	 * @param jsonPath
	 */

	public static List<String> getArrayArray(JSONArray jsonArray, String jsonPath) {
		Object object = JSONPath.eval(jsonArray, jsonPath);
		List<String> result = new ArrayList<>();
		if (object != null && object instanceof JSONArray) {
			JSONArray arr = (JSONArray) object;
			for(Object o : arr){
				result.add(o.toString());
			}
		}
		return result;
	}


	public static String getConcurrentMapValue(String recvMsg,String path,String paraCode) throws Exception {
		String[] pathArr=path.split(";");
		String[] paraCodeArr=paraCode.split(";");
		List<Map<String,String>> paramMapList = new ArrayList<>();
		JSONObject jsonObject=JSONObject.parseObject(recvMsg);
		Map<String,List<String>> mapResult=new LinkedHashMap<>();
		List<String> singleList;
		Object obj;
		try {
			for (int i = 0; i < paraCodeArr.length; i++) {
				obj = JSONPath.eval(jsonObject, pathArr[i]);
				if (obj instanceof List) {
					List<Object> objectList=(List<Object>) obj;
					singleList= objectList.stream().map(x -> x + "").collect(Collectors.toList());
				} else {
					singleList = new ArrayList<>();
					singleList.add(obj + "");
				}
				mapResult.put(paraCodeArr[i], singleList);
			}
			int size = mapResult.get(paraCodeArr[0]).size();
			for (int i = 0; i < size; i++) {
				Map<String, String> rowMap = new HashMap<>();
				for (int j = 0; j < paraCodeArr.length; j++) {
						rowMap.put(paraCodeArr[j],
								mapResult.get(paraCodeArr[j]).size() > i ? mapResult.get(paraCodeArr[j]).get(i) : null);
				}
				paramMapList.add(rowMap);
			}
			return JSON.toJSONString(paramMapList, SerializerFeature.WriteMapNullValue);
		}catch (Exception ex){
			log.error(ExceptionUtils.getStackTrace(ex));
			return "";
		}
	}
	public static String obj2Json(Object object) {
		return JSON.toJSONString(object, SerializerFeature.DisableCircularReferenceDetect,
				SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty);
	}

	/**
	 * 抽取所有子级字段
	 * @param parent
	 * @param childNodeName
	 * @param extractAttr
	 * @param list
	 */
	public static void extractAllNodes(JSONObject parent, String childNodeName, String[] extractAttr,List<Map<String, String>> list){
		Map<String, String> map = new HashMap<>();
		for(String attr : extractAttr){
			map.put(attr, parent.getString(attr));
		}
		list.add(map);
		Object o = parent.get(childNodeName);
		if(o != null) {
			if (o instanceof JSONObject) {
				JSONObject child = (JSONObject) o;
				extractAllNodes(child, childNodeName, extractAttr, list);
			}
			if(o instanceof  JSONArray){
				JSONArray children = (JSONArray) o;
				for(int i=0; i<children.size(); i++){
					JSONObject child = children.getJSONObject(i);
					extractAllNodes(child, childNodeName, extractAttr, list);
				}
			}
		}
	}

	public static <T> T json2Obj(String json, Class<T> clazz) {
		return JSON.parseObject(json, clazz);
	}

	public static <T> List<T> json2List(String json, Class<T> clazz) {
		return JSON.parseArray(json, clazz);
	}
}
